// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: donggu

#pragma once

// std
#include <map>
#include <memory>
#include <regex>
#include <string>
#include <utility>
#include <vector>

// internal
#include "coin2/base/log.h"
#include "coin2/exchange/base/feed/processor.h"
#include "coin2/exchange/base/market/enums.h"
#include "coin2/exchange/di/constant.h"

namespace coin2::exchange::huobi::feed_v1 {

namespace impl {
using namespace std::string_literals;
using coin2::exchange::base::executor::TopicRecordPacket;
using coin2::exchange::base::symbology::ExchangeType;
using coin2::exchange::base::symbology::MarketType;

struct HuobiChannel {
  std::string native_symbol;
  std::string type;

  static HuobiChannel Parse(const std::string& ch) {
    static const std::regex CHANNEL_REGEX(
        R"((market|public)\.([\w\-]+)\.(trade\.detail|depth\.step0|depth\.step6|mbp\.150|mbp\.5|mbp\.20|mbp\.400|bbo|depth\.size_20.high_freq|liquidation_orders|etp|funding_rate|kline\.(?:1min|5min|15min|30min|60min|4hour|1day|1mon)))");

    /*
    "market.btcusdt.trade.detail"
    "market.ethusdt.trade.detail"
    "market.btcusdt.depth.step0"
    "market.ethusdt.depth.step6"
    "market.btcusdt.mbp.150"
    "market.btcusdt.bbo"
    "market.btcusdt.depth.size_20.high_freq"
    "public.BTC-USD.liquidation_orders"
    "public.BTC-USDT.funding_rate"
    "market.BTC-USD.kline.1day"
    */
    std::smatch m;
    std::regex_match(ch, m, CHANNEL_REGEX);
    CHECK_EQ_THROW(m.size(), 4) << "unknown channel: " << ch;
    return HuobiChannel{m[2], m[3]};
  }
};

class HuobiFeedProcessor : public base::feed::FeedParsingProcessor {
 public:
  explicit HuobiFeedProcessor(
      const std::string& system_name,
      const coin2::exchange::di::ConstantInjection& ci,
      const feed::RawParserConfig& config,
      const MarketExchangeApi& mea)
      : FeedParsingProcessor(
            system_name,
            mea,
            ci,
            config,
            "cc/coin2/exchange/huobi/feed_v1/schema.json") {}

  void OnTopicRecord(const TopicRecordPacket& packet) override;
};

}  // namespace impl

using impl::HuobiChannel;
using impl::HuobiFeedProcessor;
}  // namespace coin2::exchange::huobi::feed_v1
